using System;
using System.Collections;
//using System.Linq;
using System.ComponentModel;
using System.Data;
//using System.Xml.Linq;
using System.Windows.Forms;
//using Utiles.UtilInfragistics;
//using clsVariables;
//'
public struct GuardaryLimpiar
{
    static GuardaryLimpiar()
    {

    }
}
public partial class mtoBase
{
    //'
    #region  Variables
    #region eTipoShowForm
    private clsVariables.eTipoShowForm p_TipoShowForm = clsVariables.eTipoShowForm.ShowDialog;
    /// <summary>
    /// Indica si el formulario sera MDI o ShowDialog
    /// </summary>
    public clsVariables.eTipoShowForm TipoShowForm
    {
        get { return p_TipoShowForm; }
        set { p_TipoShowForm = value; }
    }
    #endregion
    public clsVariables.e_TipoOrigen p_OrigenDatos;
    public string p_ObjetoFuente;
    //private ArrayList aListCtrlsRowNav; //Lista de controles personalizados de SCP
    private System.Collections.Generic.Dictionary<string, Control> _dicScpCtrlsDependientes;
    private ArrayList aListTodosCtrls; //Lista de Todos los controles
    public Ctrl_UltraGrid NavUgDatos; //Grid datos del navegador (inferior)

    #region AlCrearRowMtoEventHandler
    public delegate void AlCrearRowMtoEventHandler();
    private AlCrearRowMtoEventHandler AlCrearRowMtoEvent;
    /// <summary>
    /// Evento q se lanza al crear la línea de MTo q se va ha insert o update pero justo antes
    /// </summary>
    public event AlCrearRowMtoEventHandler AlCrearRowMto
    {
        add
        {
            AlCrearRowMtoEvent = (AlCrearRowMtoEventHandler)Delegate.Combine(AlCrearRowMtoEvent, value);
        }
        remove
        {
            AlCrearRowMtoEvent = (AlCrearRowMtoEventHandler)Delegate.Remove(AlCrearRowMtoEvent, value);
        }
    }
    #endregion

    public delegate void AntesGuardarEventHandler(object sender, CancelEventArgs e);
    private AntesGuardarEventHandler AntesGuardarEvent;
    public event AntesGuardarEventHandler AntesGuardar
    {
        add
        {
            AntesGuardarEvent = (AntesGuardarEventHandler)Delegate.Combine(AntesGuardarEvent, value);
        }
        remove
        {
            AntesGuardarEvent = (AntesGuardarEventHandler)Delegate.Remove(AntesGuardarEvent, value);
        }
    }

    public delegate void AntesEditarEventHandler(object sender, CancelEventArgs e);
    private AntesEditarEventHandler AntesEditarEvent;
    public event AntesEditarEventHandler AntesEditar
    {
        add
        {
            AntesEditarEvent = (AntesEditarEventHandler)Delegate.Combine(AntesEditarEvent, value);
        }
        remove
        {
            AntesEditarEvent = (AntesEditarEventHandler)Delegate.Remove(AntesEditarEvent, value);
        }
    }

    public delegate void AntesDuplicarEventHandler(object sender, CancelEventArgs e);
    private AntesDuplicarEventHandler AntesDuplicarEvent;
    public event AntesDuplicarEventHandler AntesDuplicar
    {
        add
        {
            AntesDuplicarEvent = (AntesDuplicarEventHandler)Delegate.Combine(AntesDuplicarEvent, value);
        }
        remove
        {
            AntesDuplicarEvent = (AntesDuplicarEventHandler)Delegate.Remove(AntesDuplicarEvent, value);
        }
    }

    public delegate void DespuesGuardarEventHandler();
    private DespuesGuardarEventHandler DespuesGuardarEvent;
    /// <summary>
    /// DEspués de pulsar el btn guardar (insertar o edición)
    /// </summary>
    public event DespuesGuardarEventHandler DespuesGuardar
    {
        add
        {
            DespuesGuardarEvent = (DespuesGuardarEventHandler)Delegate.Combine(DespuesGuardarEvent, value);
        }
        remove
        {
            DespuesGuardarEvent = (DespuesGuardarEventHandler)Delegate.Remove(DespuesGuardarEvent, value);
        }
    }
    //
    public delegate void DespuesEditarEventHandler();
    private DespuesEditarEventHandler DespuesEditarEvent;
    /// <summary>
    /// Después de pulsar el botón editar
    /// </summary>
    public event DespuesEditarEventHandler DespuesPulsarEditar
    {
        add
        {
            DespuesEditarEvent = (DespuesEditarEventHandler)Delegate.Combine(DespuesEditarEvent, value);
        }
        remove
        {
            DespuesEditarEvent = (DespuesEditarEventHandler)Delegate.Remove(DespuesEditarEvent, value);
        }
    }
    //
    public delegate void DespuesDuplicarEventHandler();
    private DespuesDuplicarEventHandler DespuesDuplicarEvent;
    public event DespuesDuplicarEventHandler DespuesDuplicar
    {
        add
        {
            DespuesDuplicarEvent = (DespuesDuplicarEventHandler)Delegate.Combine(DespuesDuplicarEvent, value);
        }
        remove
        {
            DespuesDuplicarEvent = (DespuesDuplicarEventHandler)Delegate.Remove(DespuesDuplicarEvent, value);
        }
    }
    //
    #region EstablecerValoresDefecto
    public delegate void EstablecerValoresDefectoHandler(); // Declare the delegate (if using non-generic pattern).
    /// <summary>
    /// Establecer los valores por defecto del mto en modo alta (o llamado especialmente)
    /// </summary>
    public event EstablecerValoresDefectoHandler EstablecerValoresDefecto; // Declare the event.
    #endregion
    #region LanzarErroresPersonalizados
    public delegate void LanzarErrorPersonalizadoHandler(CancelEventArgs e, Exception Err);
    /// <summary>
    /// Para lanzar errores personalizados del form de mto cancelando (o no) el general
    /// </summary>
    public event LanzarErrorPersonalizadoHandler LanzarErrorPersonalizado;
    #endregion
    //
    #region DespuesSalir
    public delegate void DespuesSalirEventHandler();
    private DespuesSalirEventHandler DespuesSalirEvent;
    public event DespuesSalirEventHandler DespuesSalir
    {
        add
        {
            DespuesSalirEvent = (DespuesSalirEventHandler)Delegate.Combine(DespuesSalirEvent, value);
        }
        remove
        {
            DespuesSalirEvent = (DespuesSalirEventHandler)Delegate.Remove(DespuesSalirEvent, value);
        }
    }
    #endregion
    //
    #region                                                                NavOrigen
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category(clsVariables.str_NombreAplicacion), Description("Navegador enlazado con este mantenimiento")]
    public navBase NavOrigen { get; set; }
    #endregion
    //
    #region                                                                RowDatos
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category(clsVariables.str_NombreAplicacion),
    Description("Row para consultar, editar o añadir pasada al mto")]
    /// <summary>
    /// DataRow pasada desde el nav (listobject de la row activa) al mto
    /// </summary>
    public DataRow RowDatosMto { get; set; }
    #endregion
    //'
    public enum eTipoAccion { Anyadir, Editar, Consultar }
    //'
    #region                                                                TipoAccion
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Category(clsVariables.str_NombreAplicacion), Description("Insertar o Edicion?")]
    public eTipoAccion TipoAccion { get; set; }
    public eTipoAccion TipoAccionMomentoLoad { get; set; }
    #endregion
    //'
    #endregion
    //'
    #region  New
    public mtoBase()
    {
        InitializeComponent(); // Llamada necesaria para el Diseñador de Windows Forms.
        // Agregue cualquier inicialización después de la llamada a InitializeComponent().
        //this.Load += this.mtoBase_Load;
        //this.FormClosed += this.mtoBase_FormClosed;
    }
    //'
    //Public Sub New(ByVal OrigenDatos As e_TipoOrigen, ByVal ObjetoFuente As String)
    //   Me.New()
    //   p_OrigenDatos = OrigenDatos : p_ObjetoFuente = ObjetoFuente
    //End Sub
    #endregion
    //
    private void mtoBase_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Dispose()
        _dicScpCtrlsDependientes = null;
        //aListCtrlsRowNav = null;
        aListTodosCtrls = null;
        if (DespuesSalirEvent != null) DespuesSalirEvent();
    }
    //'
    private void mtoBase_Load(object sender, EventArgs e)
    {
        //Config Barra
        Utiles.UtilInfragistics.Ctrl_UltraToolbarsManager.ScpEstandarBarra(ref utmCabecera);
        clsControlColores.CambiarColorBarra(utmCabecera);
        //
        TipoAccionMomentoLoad = TipoAccion;
        _dicScpCtrlsDependientes = new System.Collections.Generic.Dictionary<string, Control>();
        //aListCtrlsRowNav = new ArrayList(); //Guardará los controles
        aListTodosCtrls = new ArrayList();
        //
        Control ctrl;
        foreach (dynamic oCtrl in Controls)
        {
            ctrl = oCtrl;
            if (oCtrl is Ctrl_Adjuntos) { aListTodosCtrls.Add(oCtrl); }//Adjuntos solo se almacena         }
            else { RecorrerControles(oCtrl); } //Buiscar controles
        }
        //
        //For Each oCtrl As Object In Controls
        //   If oCtrl.HasChildren Then
        //      AsignarValorControl(oCtrl)
        //   ElseIf TypeOf oCtrl Is Infragistics.Win.UltraWinTabControl.UltraTabControl Then
        //      For x As Integer = 0 To oCtrl.Tabs.Count - 1
        //         AsignarValorControl(.Tabs(x).TabPage)
        //      Next
        //   ElseIf Not TypeOf oCtrl Is Ctrl_Adjuntos Then
        //      'Not TypeOf oCtrl Is Ctrl_ComboDoble Then
        //      AsignarValorControl(oCtrl)
        //   End If
        //Next
        //
        _mtoBase_Toolbars_Dock_Area_Bottom.Enabled = true;
        _mtoBase_Toolbars_Dock_Area_Left.Enabled = true;
        _mtoBase_Toolbars_Dock_Area_Right.Enabled = true;
        _mtoBase_Toolbars_Dock_Area_Top.Enabled = true;
        //utmCabecera.Enabled = True
        if (!DesignMode) { SetImagenesComportamientoBotones(); }
        StartPosition = FormStartPosition.CenterScreen;
        if (!DesignMode) { if (EstablecerValoresDefecto != null) { EstablecerValoresDefecto(); } }
        if (TipoAccion == eTipoAccion.Anyadir)
        {
            EditarDatos(); TipoAccion = eTipoAccion.Anyadir;
            // if (!DesignMode) { if (EstablecerValoresDefecto != null) { EstablecerValoresDefecto(); } } //Sino pongo  if (!DesignMode) en modo diseño da error
        }
        //'
    }
    //'
    private void RecorrerControles(Control oCtrl2Aux)
    {
        dynamic oCtrl2 = oCtrl2Aux;
        //Si es un control de infragistics no se puede recorrer con ControlForm.Controls pq. devuelve 0 ya que es
        //windows.forms.controls. DE momento lo soluciono así...
        //If ControlForm.GetType.FullName = "Infragistics.Win.UltraWinToolbars.UltraToolbarsDockArea" Then CambiarColorBarra(ControlForm.toolbarsmanager)
        //RecorrerControlesAplicarEstilos(ctlControl)
        //
        //If TypeOf ctlControl Is Infragistics.Win.UltraWinTabControl.UltraTabControl Then
        //   For x As Integer = 0 To ctlControl.Tabs.Count - 1
        //      AsignarValorControl(ctlControl.Tabs(x).TabPage)
        //   Next
        //   '
        //ElseIf Not ctlControl.HasChildren Then
        //   AsignarValorControl(ctlControl)
        //   '
        //ElseIf ctlControl.HasChildren Then
        //   RecorrerControles(ctlControl)
        //End If
        //
        //Console.WriteLine("RecorrerControles: " + oCtrl2.Name);
        if (!AsignarValorControl(oCtrl2))
        {
            foreach (dynamic oCtrl3 in oCtrl2.Controls)
            {
                if (oCtrl3.HasChildren) { RecorrerControles(oCtrl3); }
                else { AsignarValorControl(oCtrl3); }
            }
        }
    }
    //'
    private bool AsignarValorControl(Control oCtrl4Aux)
    {
        dynamic oCtrl4 = oCtrl4Aux;
        string strNombreControlSinPrefijo = oCtrl4Aux.Name; // string.Empty;
        bool bolIndependiente = true;
        bool Ret = false;
        //'
        //'
        try
        {
            //Inicio Chapuza
            //Si es un control de infragistics no se puede recorrer con ControlForm.Controls pq. devuelve 0 ya que es
            //windows.forms.controls. DE momento lo soluciono así...
            //If ControlForm.GetType.FullName = "Infragistics.Win.UltraWinToolbars.UltraToolbarsDockArea" Then CambiarColorBarra(ControlForm.toolbarsmanager)
            //RecorrerControlesInfragistics(ctlControl)
            //---fin Chapuza
            //
            //With oCtrl
            //
            //If Not RowDatos Is Nothing Then 'Si vienen datos. REllenar con lo q venga
            //
            try
            { bolIndependiente = oCtrl4.bol_Independiente; } //Si peta es un control normal y no recupero datos         
            catch (Exception) { }
            //
            if (!bolIndependiente) //Controles personales pq. bolIndependiente es False
            {
                string strNombre = oCtrl4.Name;
                strNombreControlSinPrefijo = Utiles.Strings.Mid(strNombre, 4, 50); //Capturar nombre control sin prefijo
                //Si es de tipo texto establecer maxlengh en el control
                //If RowDatos.Item(strNombreControlSinPrefijo) = 1 Then 'TODO: Si es tipo texto
                //   .MaxLength = 50
                //ElseIf RowDatos.Item(strNombreControlSinPrefijo) = 2 Then 'TODO: Si es tipo numérico
                //   .MaskInput = "nnnnnnnnn"
                //End If
                //
                //Añadir
                if (oCtrl4 is Ctrl_UltraComboEditor) { oCtrl4.RecargarDatos(); } //Carga combo //Ya lo hago en el Load    
                if (TipoAccion == eTipoAccion.Anyadir) //En añadir solo carga los combos. El resto no
                {
                    //if (oCtrl4 is Ctrl_UltraComboEditor) { oCtrl4.RecargarDatos(); } //Carga combo //Ya lo hago en el Load               
                }
                //
                //Editar
                else if (TipoAccion == eTipoAccion.Consultar)
                {
                    RellenarValorControl(oCtrl4Aux);
                }
                _dicScpCtrlsDependientes.Add(strNombreControlSinPrefijo.ToLower(), oCtrl4);
                //Console.WriteLine("Control: " + strNombreControlSinPrefijo);
                //aListCtrlsRowNav.Add(oCtrl4); //Guardamos control en lista. Si es añadir vendrá sin valor sino con valor
                Ret = true;
                //
            }
            //Console.WriteLine(oCtrl4.Name);
            oCtrl4.Enabled = false; //Desactivar todos por defecto
            aListTodosCtrls.Add(oCtrl4);
            return Ret;
            //End With
            //'
        }
        catch (Exception ex)
        {
            Utiles.Errores.LanzarError(this, string.Format("AsignarValorControl: Campo: {0} Con Valor {1}) ", strNombreControlSinPrefijo, RowDatosMto[strNombreControlSinPrefijo]), "", ex, MessageBoxIcon.Exclamation, true);
            return Ret;
        }
    }
    /// <summary>
    /// Coge los controles tipo dependientes y les asigna el valor de RowDatosMto
    /// </summary>
    /// <param name="objCtrl"></param>
    private void RellenarValorControl(Control objCtrl)
    {
        dynamic oCtrl4 = objCtrl;
        string strNombreControlSinPrefijo = Utiles.Strings.Mid(objCtrl.Name, 4, 50);
        //
        try
        {
            if (oCtrl4 is Ctrl_UltraComboEditor)
            {
                oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], null);
            }
            else if (oCtrl4 is Ctrl_UltraCheckEditor)
            {
                oCtrl4.Checked = clsBBDD.DevolverBooleano(RowDatosMto[strNombreControlSinPrefijo]); //si es nulo devuelve false
            }
            else if (oCtrl4 is Ctrl_UltraDateTimeEditor)
            {
                oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], DBNull.Value);
            }
            else if (oCtrl4 is Ctrl_UltraNumericEditor)
            {
                oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], 0);
            }
            else if (oCtrl4 is Ctrl_UltraTextEditor)
            {
                oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], DBNull.Value);
                //No acaba de funcionar bien. Para bbdd nuevas si pero para existentes recupera el Lengh q le da la gana
                // .MaxLength = RowDatos.Table.Columns(strNombreControlSinPrefijo).MaxLength 'Tamaño máximo
            }
            else if (oCtrl4 is Ctrl_ComboDoble)
            {
                //oCtrl4.CargaCombos() 'Cargar datos combo doble
                oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], DBNull.Value);
            }
            else { oCtrl4.Value = Utiles.General.ScpIsNull(RowDatosMto[strNombreControlSinPrefijo], DBNull.Value); }
            //
        }
        catch (Exception ex)
        {
            if (clsVariables.bol_Pruebas) MessageBox.Show(String.Format("Error al pasar valor a control. Control: '{0}'. Revise campo se encuentra en la vista", strNombreControlSinPrefijo));
            throw ex;
        }
    }
    //'
    private void SetImagenesComportamientoBotones()
    {
        //Imagenes botones
        Infragistics.Win.UltraWinToolbars.SharedProps with_2 = utmCabecera.Tools["GuardarySalir"].SharedProps;
        with_2.AppearancesLarge.Appearance.Image = clsImagenes.GuardarySalir;
        with_2.AppearancesSmall.Appearance.Image = with_2.AppearancesLarge.Appearance.Image;
        with_2.Enabled = false;
        Infragistics.Win.UltraWinToolbars.SharedProps with_3 = utmCabecera.Tools["Salir"].SharedProps;
        with_3.AppearancesLarge.Appearance.Image = clsImagenes.Salir;
        with_3.AppearancesSmall.Appearance.Image = with_3.AppearancesLarge.Appearance.Image;
        Infragistics.Win.UltraWinToolbars.SharedProps with_4 = utmCabecera.Tools["Guardar"].SharedProps;
        with_4.AppearancesLarge.Appearance.Image = clsImagenes.Guardar;
        with_4.AppearancesSmall.Appearance.Image = with_4.AppearancesLarge.Appearance.Image;
        with_4.Enabled = false;
        //.EnabledResolved =  'TODO: Establacer permisos
        Infragistics.Win.UltraWinToolbars.SharedProps with_5 = utmCabecera.Tools["Editar"].SharedProps;
        with_5.AppearancesLarge.Appearance.Image = clsImagenes.Editar;
        with_5.AppearancesSmall.Appearance.Image = with_5.AppearancesLarge.Appearance.Image;
        with_5.Enabled = true;
        //.EnabledResolved =  'TODO: Establacer permisos
        Infragistics.Win.UltraWinToolbars.SharedProps with_6 = utmCabecera.Tools["Duplicar"].SharedProps;
        with_6.Visible = clsVariables.bol_Pruebas; //TODO: Quitar
        with_6.AppearancesLarge.Appearance.Image = clsImagenes.Duplicar;
        with_6.AppearancesSmall.Appearance.Image = with_6.AppearancesLarge.Appearance.Image;
        with_6.Enabled = false;
        //.EnabledResolved =  'TODO: Establacer permisos
        Infragistics.Win.UltraWinToolbars.SharedProps oGuardaryLimpiar = utmCabecera.Tools["GuardaryLimpiar"].SharedProps;
        oGuardaryLimpiar.AppearancesSmall.Appearance.Image = clsImagenes.GuardaryLimpiar;
        oGuardaryLimpiar.Enabled = false;
    }
    //'
    #region  ToolClik y acciones
    public void utmCabecera_ToolClick(Object sender, Infragistics.Win.UltraWinToolbars.ToolClickEventArgs e)
    {
        CancelEventArgs eCancel = new CancelEventArgs();
        //Control oCombo;
        //'
        try
        {
            Cursor = Cursors.WaitCursor;
            switch (e.Tool.Key)
            {
                case "Salir":
                    //oCombo = this.ActiveControl; //  Utiles.UtilControlesNET.GetFocusControl();
                    //if (oCombo == null) { } //Si es combo o combodoble cierro sino nada
                    //else if (  oCombo is Ctrl_UltraComboEditor) { ((Ctrl_UltraComboEditor) oCombo).SelectedIndex=0;}
                    //else if (oCombo is Ctrl_ComboDoble) { ((Ctrl_ComboDoble)oCombo).SelectedIndex = 0;};
                    //try { ((dynamic)oCombo).SelectedIndex = 0; }
                    //catch (Exception) { }
                    //
                    Close(); //No se limpia aunque haga el close pq. está 'pillado' por un woth parece... me conviene dejarlo así creo
                    break;
                case "Guardar":
                    if (AntesGuardarEvent != null) AntesGuardarEvent(this, eCancel);
                    if (!eCancel.Cancel) { GuardarDatos(); }
                    break;
                //
                case "GuardarySalir":
                    if (AntesGuardarEvent != null) AntesGuardarEvent(this, eCancel);
                    if (!eCancel.Cancel) { GuardarDatos(); Close(); }
                    break;
                //
                case "GuardaryLimpiar":
                    if (AntesGuardarEvent != null) AntesGuardarEvent(this, eCancel);
                    if (!eCancel.Cancel)
                    {
                        if (GuardarDatos())
                        {
                            TipoAccion = eTipoAccion.Anyadir;
                            RowDatosMto = ((DataTable)NavOrigen.ugCampos.DataSource).NewRow();
                            //LimpiarControles();
                            openChildWindow();
                        }
                    }
                    break;
                //
                case "Duplicar":
                    if (AntesDuplicarEvent != null) AntesDuplicarEvent(this, eCancel);
                    if (!eCancel.Cancel) { DuplicarDatos(); }
                    break;
                //
                case "Editar":
                    if (AntesEditarEvent != null)
                        AntesEditarEvent(this, eCancel);
                    if (!eCancel.Cancel) { EditarDatos(); }
                    break;
            }
            //
        }
        catch (Exception ex)
        { Utiles.Errores.LanzarError(this, "utmCabecera_ToolClick", "", ex, MessageBoxIcon.Exclamation, true); }
        finally
        { Cursor = Cursors.Default; }
    }
    
    private void LimpiarControles()
    {
        foreach (string strKey in _dicScpCtrlsDependientes.Keys)
        {
            //Console.WriteLine("LimpiarControles:" + strKey);
            //((Control)_dicScpCtrlsDependientes[strKey]).Text = "";
            RellenarValorControl(((Control)_dicScpCtrlsDependientes[strKey])); //Asignar valor al control
        }
        if (EstablecerValoresDefecto != null) { EstablecerValoresDefecto(); } //rellenar valores defecto
        //foreach (Control objCtrl in aListTodosCtrls)
        //{
        //   objCtrl.Text = "";
        //}
    }

    private void openChildWindow()
    {
        this.Hide();
        Close();
        //Form2 childForm = new Form2();
        //childForm.ShowDialog();

        this.FormClosed += NavOrigen.AnyadirDesdeGuardarYLimpiar;
    }

    private void DuplicarDatos()
    {
        Exception Ex = null;
        //'
        try
        {
            if (DespuesDuplicarEvent != null) DespuesDuplicarEvent();
            //
            //Ex = EjecutarUpdate(RowDatos.Table, "SELECT * FROM " & p_ObjetoFuente, p_OrigenDatos)
            if (Ex == null)
            { NavUgDatos.DataBind(); }
            else
            { throw (new Exception(Ex.Message, Ex)); }
            //'
        }
        catch (Exception ex2)
        { Utiles.Errores.LanzarError(this, "GuardarDatos", "", ex2, MessageBoxIcon.Exclamation, true); }
    }
    //'
    private bool GuardarDatos()
    {
        string strNombreControlSinPrefijo = string.Empty;
        Exception Ex = null;
        clsBBDD oclsBBDD = new clsBBDD();
        DataRow RowVista;
        string strFiltro = string.Empty;
        bool _boolObjetoFuenteEsVista = false;
        dynamic oCtrl; //no se puede usar ni object ni control por .name y .value... y da por saco al debugar
        string strDtCampoActual = "";
        string strIdsSql = "";
        string sSQl = "";
        //'
        try
        {
            //Volcar conrtenido de los controles al row
            foreach (string strKey in _dicScpCtrlsDependientes.Keys)
            {
                oCtrl = _dicScpCtrlsDependientes[strKey];
                //foreach (dynamic oCtrl in aListCtrlsRowNav) //Son todos los dependientes del row del nav !!
                //{
                //
                //If Not RowDatos Is Nothing Then 'Si vienen datos. REllenar con lo q venga
                //
                strNombreControlSinPrefijo = Utiles.Strings.Mid(oCtrl.Name, 4, 50); //Capturar nombre control sin prefijo
                //          
                //Console.WriteLine("<GuardarDatos>" + strNombreControlSinPrefijo);
                if (((DataRow)RowDatosMto).Table.Columns.Contains(strNombreControlSinPrefijo)) //Si existe la columna en la tabla recupera el valor
                {
                    //
                    if (oCtrl is Ctrl_UltraComboEditor)
                    {
                        if (((Ctrl_UltraComboEditor)oCtrl).SelectedItem == null)
                        { throw new Exception("El combo " + ((Ctrl_UltraComboEditor)oCtrl).Name + " no tiene seleccionado un valor válido"); }

                        RowDatosMto[strNombreControlSinPrefijo] = Utiles.General.ScpIsNull(oCtrl.Value, DBNull.Value);
                    }
                    else if (oCtrl is Ctrl_UltraCheckEditor)
                    {
                        RowDatosMto[strNombreControlSinPrefijo] = oCtrl.CheckState; //si es nulo devuelve false
                    }
                    else if (oCtrl is Ctrl_UltraDateTimeEditor)
                    {
                        RowDatosMto[strNombreControlSinPrefijo] = Utiles.General.ScpIsNull(clsBBDD.TratamientoValorSegunProvider(oCtrl.Value), DBNull.Value);
                    }
                    else if (oCtrl is Ctrl_UltraNumericEditor)
                    {
                        RowDatosMto[strNombreControlSinPrefijo] = Utiles.General.ScpIsNull(oCtrl.Value, 0);
                    }
                    else if (oCtrl is Ctrl_UltraTextEditor)
                    {
                        RowDatosMto[strNombreControlSinPrefijo] = Utiles.General.ScpIsNull(oCtrl.Text, string.Empty);
                    }
                    else if (oCtrl is Ctrl_ComboDoble)
                    {
                        //if (oCtrl.Value == 0)
                        if (!((Ctrl_ComboDoble)oCtrl).bolValoresCombosCorrectos)
                        { throw new Exception("El combo " + ((Ctrl_ComboDoble)oCtrl).Name + " no tiene seleccionado un valor válido"); }

                        RowDatosMto[strNombreControlSinPrefijo] = oCtrl.Value;
                    }
                    else
                    { RowDatosMto[strNombreControlSinPrefijo] = Utiles.General.ScpIsNull(oCtrl.Value, DBNull.Value); }
                }
                //
                //End If
                //
            }

            if (AlCrearRowMtoEvent != null) AlCrearRowMtoEvent();

            //
            ActualizarIdusuariocyFechaC(); //POner usuarioCC y COntrolCambios
            //
            //Tiene q éstar aquí pq. sino RowDatosMto.Table no tiene nada q actualizar                     
            if (TipoAccion == eTipoAccion.Anyadir)
            {
                //No hace ni puto caso de esto pq. aunque le toque el 4 por max + 1 el identity tiene en cuenta los eliminados y podría poner p.e. el 27 como id
                ////Obtener el id max de cada campo primary key si es insert y actualizar la fila... en update ya tenemos el id y no hace falta
                //foreach (DataColumn Dc in RowDatosMto.Table.PrimaryKey)
                //{if (Dc.AutoIncrement) { strIdsMax = "MAX(" + Dc.ColumnName + ") as " + Dc.ColumnName + ","; }}
                //if (!string.IsNullOrWhiteSpace(strIdsMax))
                //{
                //    strIdsMax = Utiles.Strings.Mid(strIdsMax, 1, strIdsMax.Length - 2);
                //    DataTable dtIdMax = clsBBDD.DtObtener("Select " + strIdsMax + " From " + p_ObjetoFuente, p_OrigenDatos, false);
                //    foreach (DataColumn Dc in dtIdMax.Rows[0].Table.Columns)
                //    { RowDatosMto[Dc.ColumnName] = ((int)dtIdMax.Rows[0][Dc.ColumnName]) + 1; }
                //}
                //
                //Agregar row al nav y refrescar
                RowDatosMto["Seleccionar"] = 0;
                RowDatosMto.Table.Rows.Add(RowDatosMto);
                NavUgDatos.Rows[NavUgDatos.Rows.Count - 1].Activate();
                NavUgDatos.DataBind(); //Con esto resituo las líneas para que el orden de columnas tenga sentido. SIEMPRE después de la linea anterior
                //NavOrigen.HabilitarConsultar_Eliminar();
            }
            DataTable Dt = RowDatosMto.Table;
            //Dt.AcceptChanges(); //no hace nada con esto antes
            Ex = clsBBDD.EjecutarUpdate(ref Dt, "SELECT * FROM " + p_ObjetoFuente, p_OrigenDatos);
            //
            //NavUgDatos.DataBind(); 
            if (Ex == null) //Sino hay error
            {
                //Obtener el id max de cada campo primary key si es insert y actualizar la row... en update ya tenemos el id y no hace falta
                if (TipoAccion == eTipoAccion.Anyadir && _boolObjetoFuenteEsVista == false) // si es _boolObjetoFuenteEsVista lo hace más adelante...
                {
                    foreach (DataColumn Dc in RowDatosMto.Table.PrimaryKey)
                    { if (Dc.AutoIncrement) { strIdsSql = Dc.ColumnName + ","; } } //Solo necesario para identitys
                    if (!string.IsNullOrWhiteSpace(strIdsSql))
                    {
                        strIdsSql = Utiles.Strings.Mid(strIdsSql, 1, strIdsSql.Length - 2);
                        sSQl = String.Format("Select {0} From {1} Where idusuarioc = {2} And fecham = '{3}'",
                                 strIdsSql, p_ObjetoFuente, clsVariables.UsuarioActualInfo.intIdUsuario,
                                 clsBBDD.TransformDate(RowDatosMto["fecham"], true)); //seleccionar una sola row de este user
                        // " Order by " + sSQl + " desc limit 1"; //obtener el último registro que inserto este user
                        DataTable dtIdMax = clsBBDD.DtObtener(sSQl, p_OrigenDatos, false);
                        foreach (DataColumn Dc in dtIdMax.Rows[0].Table.Columns)
                        { RowDatosMto[Dc.ColumnName] = dtIdMax.Rows[0][Dc.ColumnName]; }
                        NavUgDatos.DataBind();
                    }
                }
                //
                _boolObjetoFuenteEsVista = NavOrigen.ObjetoFuente.ToLower().StartsWith("vis");
                if (_boolObjetoFuenteEsVista) //Si la tabla del nav es una vista
                {
                    //
                    foreach (DataColumn Dc in RowDatosMto.Table.PrimaryKey)
                    {
                        if (Dc.DataType == Type.GetType("System.String") || Dc.DataType == Type.GetType("System.TimeSpan") || Dc.DataType == Type.GetType("System.DateTime"))
                        { strFiltro += string.Format(" And {0}=\'{1}\'", Dc.ColumnName, RowDatosMto[Dc.ColumnName]); } //Si es del tipo string o date
                        else
                        { strFiltro += string.Format(" And {0}={1}", Dc.ColumnName, RowDatosMto[Dc.ColumnName]); } //Otro tipo
                    }
                    //
                    //Volcar los datos de vista al row editado o insertado para q el nav lo muestre
                    RowVista = clsBBDD.DtObtener(String.Format("SELECT * FROM {0} Where 1 = 1 {1}", NavOrigen.ObjetoFuente, strFiltro), NavOrigen.OrigenDatos, false).Rows[0];
                    //
                    foreach (DataColumn Dcc in RowVista.Table.Columns) //Esto no quita q tenga q refrescar el navegador la línea activa después
                    {
                        //If Not RowDatos.Table.Columns.Contains(.ColumnName) Then
                        RowDatosMto[Dcc.ColumnName] = RowVista[Dcc.ColumnName];
                        //End If
                    }
                }
                //
                //Pasarle al row de mto el user creador y modificar actual. Esos campos son de la vista y en la tbl no están, por eso
                //los paso al row del mto para poder refrescarlos en el nav
                if (((DataTable)NavUgDatos.DataSource).Columns.Contains("nombreusuariocreador"))
                {
                    if (TipoAccion == eTipoAccion.Anyadir)
                    {
                        if (RowDatosMto.Table.Columns.Contains("nombreusuariocreador"))
                        { RowDatosMto["nombreusuariocreador"] = clsVariables.UsuarioActualInfo.strNombreUsuario; }
                    }
                    if (RowDatosMto.Table.Columns.Contains("nombreusuariomodificador"))
                    { RowDatosMto["nombreusuariomodificador"] = clsVariables.UsuarioActualInfo.strNombreUsuario; }
                }
                //
                //Pasar los fk al mto para que no se quede en 0
                // foreach (dynamic oCtrl in aListCtrlsRowNav) //Son todos los dependientes !!
                foreach (DataColumn Dc in RowDatosMto.Table.PrimaryKey)
                {
                    strDtCampoActual = Dc.ColumnName;
                    if (_dicScpCtrlsDependientes.ContainsKey(strDtCampoActual.ToLower())) //Si el control existe en la colección..
                    {
                        oCtrl = _dicScpCtrlsDependientes[strDtCampoActual.ToLower()];
                        try
                        { oCtrl.Value = RowDatosMto[strDtCampoActual]; }
                        catch (Exception)
                        { oCtrl.Text = RowDatosMto[strDtCampoActual]; throw; }
                    }
                }
                //
                if (TipoAccion == eTipoAccion.Anyadir)
                {
                    NavOrigen.TotalRegistros = NavUgDatos.Rows.Count;
                    TipoAccion = eTipoAccion.Editar;
                }//Si estamos en añadir }
                else
                {
                    //NavUgDatos.DataBind(); //: NavUgDatos.ActiveRow.Cells("Seleccionar").Value = 0
                    NavOrigen.RefrescarRowActual(RowDatosMto);// NavOrigen.AplicarFiltro(); //Refrescar row activa del nav con el mto en vez de aplicar filtro de nuevo
                }
            }
            else
            {
                if (TipoAccion == eTipoAccion.Anyadir) { RowDatosMto.Table.Rows.Remove(RowDatosMto); }
                throw (new Exception(Ex.Message, Ex));
            }
            //NavUgDatos.DataBind() 'Tanto si hay error como sino refrescar grid
            //            
            if (DespuesGuardarEvent != null) DespuesGuardarEvent();
            //
            this.Focus();
            MessageBox.Show("La operación se ha completado con éxito", "Ok");
            utmCabecera.Tools["Duplicar"].SharedProps.Enabled = true; //Duplicar registro habilitado
            Dt.AcceptChanges();  //Aceptamos los cambios... sino por toquetear se piensa que hay cmbios pendientes y los intenta updatar de nuevo
            return true;
        }
        catch (Exception ex2)
        {
            CancelEventArgs e = new CancelEventArgs();
            if (LanzarErrorPersonalizado != null) { LanzarErrorPersonalizado(e, ex2); }
            if (e.Cancel != true) { TrataErroresGenericos(e, ex2); }
            if (e.Cancel != true) { Utiles.Errores.LanzarError(this, "GuardarDatos", "", ex2, MessageBoxIcon.Exclamation, true); }
            return false;
        }
        finally { oclsBBDD = null; }
    }
    //'
    /// <summary>
    /// Gestion usuario. Si es alta pone lo mismo en usuarioc/usuariom y fechac/fecham sino solo actualiza
    /// usuariom/fecham
    /// </summary>
    /// <remarks></remarks>
    private void ActualizarIdusuariocyFechaC()
    {
        if (TipoAccion == eTipoAccion.Anyadir)
        {
            RowDatosMto["Idusuarioc"] = clsVariables.UsuarioActualInfo.intIdUsuario;
            RowDatosMto["fechac"] = clsBBDD_MySQL.cFecha(DateTime.Now);
        }
        //
        RowDatosMto["Idusuariom"] = clsVariables.UsuarioActualInfo.intIdUsuario;
        RowDatosMto["fecham"] = clsBBDD_MySQL.cFecha(DateTime.Now);
    }
    //'
    private void EditarDatos() //!!Editar
    {
        try
        {
            TipoAccion = eTipoAccion.Editar;
            utmCabecera.Tools["Guardar"].SharedProps.Enabled = true;
            utmCabecera.Tools["GuardarySalir"].SharedProps.Enabled = true;
            utmCabecera.Tools["GuardaryLimpiar"].SharedProps.Enabled = true;
            utmCabecera.Tools["Duplicar"].SharedProps.Enabled = true;
            utmCabecera.Tools["Editar"].SharedProps.Enabled = false;
            //
            foreach (dynamic oCtrl in aListTodosCtrls) // Controls
            {
                //
                try
                { UtilControlesBase.ActivarONoSegunTipoCampo(oCtrl, this.TipoAccion); }
                catch (Exception)
                { oCtrl.Enabled = true; }
                //
                //If TypeOf oCtrl Is Ctrl_UltraTextEditor OrElse TypeOf oCtrl Is Ctrl_UltraNumericEditor Then
                //   UtilControlesBase.ActivarONoSegunTipoCampo(oCtrl)
                //Else
                //   oCtrl.Enabled = True
                //End If
                //
            }
            if (DespuesEditarEvent != null) DespuesEditarEvent();
        }
        catch (Exception ex)
        {
            Utiles.Errores.LanzarError(this, "GuardarDatos", "", ex, MessageBoxIcon.Exclamation, true);
        }
    }
    #endregion
    //'
    /// <summary>
    /// Tratamiento de algunos mensajes de error del mto según dataprovider
    /// </summary>
    /// <param name="e"></param>
    /// <param name="Err"></param>
    private void TrataErroresGenericos(System.ComponentModel.CancelEventArgs e, Exception Err)
    {
        string strNuevoError = "";
        string strErr = Err.Message.ToString().Trim().ToLower();
        //
        switch (clsVariables.e_ProviderNombreAplicacion)
        {
            case clsVariables.eProviderNombre.Ninguno:
                break;
            case clsVariables.eProviderNombre.Odbc:
                break;
            case clsVariables.eProviderNombre.OleDb:
                break;
            case clsVariables.eProviderNombre.OracleClient:
                break;
            case clsVariables.eProviderNombre.SqlClient:
                break;
            case clsVariables.eProviderNombre.SqlServerCe:
                break;
            case clsVariables.eProviderNombre.SqlServerCe35:
                break;
            case clsVariables.eProviderNombre.OracleDataAccessClient:
                break;
            case clsVariables.eProviderNombre.MySqlClient:
                //Error clave duplicada                      
                if (strErr.IndexOf("duplicate entry") != -1) //Duplicate entry '701' for key 'codsocio'
                {
                    int posicioncampoduplicado = strErr.IndexOf("for key '");
                    string strCampoDuplicado = Utiles.Strings.Mid(strErr, posicioncampoduplicado + 10, 100);
                    strCampoDuplicado = strCampoDuplicado.Replace("'", "");
                    strNuevoError = strErr.Replace("duplicate entry", "Valor duplicado:");
                    strNuevoError = strNuevoError.Replace("for key", "para el campo:");
                    strNuevoError = strNuevoError.Replace(strCampoDuplicado, clsVariables.RetCamposDescripcion(strCampoDuplicado));
                    e.Cancel = true;
                }
                //
                //Otro...
                break;
            default:
                break;
        }
        //
        if (e.Cancel == true)
        {
            Utiles.Errores.LanzarError(this, "GuardarDatos",
                String.Format("{0}{1}No se continuará el alta.", strNuevoError, Environment.NewLine), null, MessageBoxIcon.Exclamation);
        }

    }
}
